const { FileUpload, UserStudyStatistics, User } = require('./model');
const { Op } = require('sequelize');

class FileDao {
  // 文件上传相关操作
  
  // 创建文件上传记录
  async createFileUpload(fileData) {
    try {
      return await FileUpload.create(fileData);
    } catch (error) {
      throw new Error(`创建文件上传记录失败: ${error.message}`);
    }
  }

  // 获取用户文件上传列表
  async getUserFileUploads(userId, options = {}) {
    try {
      const { page = 1, limit = 10, file_type, usage_type, status } = options;
      const offset = (page - 1) * limit;
      
      const whereClause = { user_id: userId };
      if (file_type) whereClause.file_type = file_type;
      if (usage_type) whereClause.usage_type = usage_type;
      if (status) whereClause.status = status;

      const { count, rows } = await FileUpload.findAndCountAll({
        where: whereClause,
        order: [['created_at', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset)
      });

      return {
        files: rows,
        total: count,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(count / limit)
      };
    } catch (error) {
      throw new Error(`获取用户文件上传列表失败: ${error.message}`);
    }
  }

  // 根据ID获取文件上传记录
  async getFileUploadById(id) {
    try {
      return await FileUpload.findByPk(id, {
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'nickname']
        }]
      });
    } catch (error) {
      throw new Error(`获取文件上传记录失败: ${error.message}`);
    }
  }

  // 更新文件上传记录
  async updateFileUpload(id, updateData) {
    try {
      const [updatedRowsCount] = await FileUpload.update(updateData, {
        where: { id }
      });
      
      if (updatedRowsCount === 0) {
        throw new Error('文件上传记录不存在');
      }
      
      return await this.getFileUploadById(id);
    } catch (error) {
      throw new Error(`更新文件上传记录失败: ${error.message}`);
    }
  }

  // 标记文件上传完成
  async markFileUploadCompleted(id, fileUrl) {
    try {
      return await this.updateFileUpload(id, {
        status: 'completed',
        file_url: fileUrl
      });
    } catch (error) {
      throw new Error(`标记文件上传完成失败: ${error.message}`);
    }
  }

  // 标记文件上传失败
  async markFileUploadFailed(id) {
    try {
      return await this.updateFileUpload(id, {
        status: 'failed'
      });
    } catch (error) {
      throw new Error(`标记文件上传失败失败: ${error.message}`);
    }
  }

  // 删除文件上传记录
  async deleteFileUpload(id) {
    try {
      const deletedRowsCount = await FileUpload.destroy({
        where: { id }
      });
      
      if (deletedRowsCount === 0) {
        throw new Error('文件上传记录不存在');
      }
      
      return true;
    } catch (error) {
      throw new Error(`删除文件上传记录失败: ${error.message}`);
    }
  }

  // 获取用户文件统计
  async getUserFileStats(userId) {
    try {
      const totalFiles = await FileUpload.count({
        where: { user_id: userId }
      });

      const fileTypeStats = await FileUpload.findAll({
        where: { user_id: userId },
        attributes: [
          'file_type',
          [FileUpload.sequelize.fn('COUNT', FileUpload.sequelize.col('id')), 'count'],
          [FileUpload.sequelize.fn('SUM', FileUpload.sequelize.col('file_size')), 'totalSize']
        ],
        group: ['file_type'],
        raw: true
      });

      const totalSize = await FileUpload.sum('file_size', {
        where: { user_id: userId }
      }) || 0;

      return {
        totalFiles,
        totalSize,
        fileTypeStats
      };
    } catch (error) {
      throw new Error(`获取用户文件统计失败: ${error.message}`);
    }
  }

  // 用户学习统计相关操作

  // 创建或更新用户学习统计
  async upsertUserStudyStatistics(userId, statisticsData) {
    try {
      const [statistics, created] = await UserStudyStatistics.upsert({
        user_id: userId,
        ...statisticsData
      });
      
      return { statistics, created };
    } catch (error) {
      throw new Error(`创建或更新用户学习统计失败: ${error.message}`);
    }
  }

  // 获取用户学习统计
  async getUserStudyStatistics(userId) {
    try {
      return await UserStudyStatistics.findOne({
        where: { user_id: userId },
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'nickname', 'avatar']
        }]
      });
    } catch (error) {
      throw new Error(`获取用户学习统计失败: ${error.message}`);
    }
  }

  // 更新用户学习统计
  async updateUserStudyStatistics(userId, updateData) {
    try {
      const [updatedRowsCount] = await UserStudyStatistics.update(updateData, {
        where: { user_id: userId }
      });
      
      if (updatedRowsCount === 0) {
        // 如果记录不存在，创建新记录
        return await UserStudyStatistics.create({
          user_id: userId,
          ...updateData
        });
      }
      
      return await this.getUserStudyStatistics(userId);
    } catch (error) {
      throw new Error(`更新用户学习统计失败: ${error.message}`);
    }
  }

  // 增加学习时长
  async addStudyTime(userId, studyTime) {
    try {
      const statistics = await this.getUserStudyStatistics(userId);
      
      if (statistics) {
        return await this.updateUserStudyStatistics(userId, {
          total_study_time: statistics.total_study_time + studyTime
        });
      } else {
        return await this.upsertUserStudyStatistics(userId, {
          total_study_time: studyTime
        });
      }
    } catch (error) {
      throw new Error(`增加学习时长失败: ${error.message}`);
    }
  }

  // 增加练习次数
  async incrementPracticeCount(userId) {
    try {
      const statistics = await this.getUserStudyStatistics(userId);
      
      if (statistics) {
        return await this.updateUserStudyStatistics(userId, {
          total_practices: statistics.total_practices + 1
        });
      } else {
        return await this.upsertUserStudyStatistics(userId, {
          total_practices: 1
        });
      }
    } catch (error) {
      throw new Error(`增加练习次数失败: ${error.message}`);
    }
  }

  // 更新最佳分数
  async updateBestScore(userId, score) {
    try {
      const statistics = await this.getUserStudyStatistics(userId);
      
      if (!statistics || score > statistics.best_score) {
        return await this.updateUserStudyStatistics(userId, {
          best_score: score
        });
      }
      
      return statistics;
    } catch (error) {
      throw new Error(`更新最佳分数失败: ${error.message}`);
    }
  }

  // 更新连续学习天数
  async updateContinuousDays(userId) {
    try {
      const statistics = await this.getUserStudyStatistics(userId);
      const today = new Date().toISOString().split('T')[0];
      
      if (!statistics) {
        return await this.upsertUserStudyStatistics(userId, {
          continuous_days: 1,
          total_days: 1,
          last_study_date: today
        });
      }

      const lastStudyDate = statistics.last_study_date;
      const yesterday = new Date();
      yesterday.setDate(yesterday.getDate() - 1);
      const yesterdayStr = yesterday.toISOString().split('T')[0];

      let continuousDays = statistics.continuous_days;
      let totalDays = statistics.total_days;

      if (lastStudyDate === today) {
        // 今天已经学习过了，不需要更新
        return statistics;
      } else if (lastStudyDate === yesterdayStr) {
        // 连续学习
        continuousDays += 1;
        totalDays += 1;
      } else {
        // 中断了连续学习
        continuousDays = 1;
        totalDays += 1;
      }

      return await this.updateUserStudyStatistics(userId, {
        continuous_days: continuousDays,
        total_days: totalDays,
        last_study_date: today
      });
    } catch (error) {
      throw new Error(`更新连续学习天数失败: ${error.message}`);
    }
  }

  // 获取学习排行榜
  async getStudyLeaderboard(options = {}) {
    try {
      const { limit = 10, type = 'study_time' } = options;
      
      let orderField = 'total_study_time';
      if (type === 'practices') {
        orderField = 'total_practices';
      } else if (type === 'continuous') {
        orderField = 'continuous_days';
      } else if (type === 'score') {
        orderField = 'best_score';
      }

      return await UserStudyStatistics.findAll({
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'nickname', 'avatar']
        }],
        order: [[orderField, 'DESC']],
        limit: parseInt(limit)
      });
    } catch (error) {
      throw new Error(`获取学习排行榜失败: ${error.message}`);
    }
  }
}

module.exports = new FileDao();
